﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using CYZHAPI.Common.tools;
using CYZHAPI.web.Middlewares;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;

namespace CYZHAPI.Middlewares
{
    public class ApiAuthorizedMiddleware
    {
        public const string AuthorizationHeader = "Authorization";
        private readonly RequestDelegate _next;
        //private readonly ApiAuthorizedOptions _options;
        private static IMemoryCache _memoryCache;
        public ApiAuthorizedMiddleware(RequestDelegate next, IMemoryCache memoryCache)
        {
            this._next = next;
            //this._options = options.Value;
            _memoryCache = memoryCache;
        }
        
        public async Task Invoke(HttpContext context)
        {
            var requestPath = context.Request.Path;
            if (requestPath.Equals("/api/login"))
            {
                await _next.Invoke(context);
            }else{
                string cookieKey = "";
                string rolid = "";
                string result;
                var Request = context.Request;
                string auth = Request.Headers[AuthorizationHeader];
                if (auth == null)
                {
                    await ReturnNoAuthorized(context);
                }else{
                    string[] Authors = MyBase64.DecodeBase64("UTF-8", auth).Split("[&]");
                    cookieKey = Authors[0];
                    rolid = Authors[1];
                    string[] cookieKeys = cryptionTool.DesDecrypt(cookieKey).Split('|');
                    string keyUser = "";
                    string[] cookieValues = new string[1];
                    bool createCache = _memoryCache.TryGetValue(cookieKeys[0], out result);
                    if (createCache)
                    {
                        keyUser = cryptionTool.DesDecrypt(cookieKeys[0],cookieKeys[1]).Split('|')[1];
                        cookieValues = result.Split('|');
                        if (!(keyUser.Equals(cookieValues[0]) && cookieKeys[1].Equals(cookieValues[1])))
                        {
                            await ReturnNoAuthorized(context);
                        }else{
                            //权限验证
                            if (!rolid.Equals("NOTROL"))
                            {
                                cookieValues[2]=cookieValues[2] == null ? "":cookieValues[2];
                                List<string> objRolList = JsonConvert.DeserializeObject<List<string>>(cryptionTool.DesDecrypt(cookieValues[2]));
                                bool b_rol = false;
                                foreach (string s in objRolList)
                                {
                                    if (s.Equals(rolid)) b_rol = true;
                                }
                                if(!b_rol){
                                    await RetrurnNotRol(context);
                                }else{
                                    await _next.Invoke(context);
                                }
                            }else{
                                await _next.Invoke(context);
                            }
                        }
                    }
                    else
                    {
                        await ReturnNoAuthorized(context);
                    }
                }
            }
            
        }
       
        private static Task ReturnNoAuthorized(HttpContext context)
        {
            BaseResponseResult response = new BaseResponseResult
            {
                code = "401",
                message = "你没有被授权!"
            };
            context.Response.StatusCode = 401;
            return context.Response.WriteAsync(JsonConvert.SerializeObject(response));
        }

        private static Task RetrurnNotRol(HttpContext context)
        {
            BaseResponseResult response = new BaseResponseResult
            {
                code = "402",
                message = "你没有权限操作该功能!"
            };
            context.Response.StatusCode = 401;
            return context.Response.WriteAsync(JsonConvert.SerializeObject(response));
        }
    }
}